#pragma once
#include "eveCommon.h"
#include <math.h>

const Real  REALZEROINTERVAL = 0.0001f;
template <class T>
bool IsZero(T t)
{
	if( t == 0 )
		return true;
	return false;
}

template <>
inline bool IsZero<Real>(Real t)
{
	if( fabs(t) < REALZEROINTERVAL )
		return true;
	return false;
}
template <class T>
struct stPoint
{
	union
	{
		T x;
		T width;
	};
	union
	{
		T y;
		T height;
	};
	stPoint() : x(0),y(0) {}
	stPoint(T _x,T _y) : x(_x),y(_y) {}
	void operator+=(const stPoint<T>& pt)
	{
		x += pt.x;
		y += pt.y;
	}

	stPoint<T> operator-(const stPoint<T>& pt) const
	{
		stPoint<T> tmp(*this);
		tmp.x -= pt.x;
		tmp.y -= pt.y;
		return tmp;
	}
};
typedef stPoint<long> stPointI;
typedef stPoint<int16> stPointI16;
typedef stPoint<Real> stPointF;
template <class T>
struct stRect
{
public:
	T left;
	T top;
	T right;
	T bottom;

public:
	stRect() : left(0),top(0),right(0),bottom(0) {}
	stRect(T l,T t,T r,T b) :
		left(l),top(t),right(r),bottom(b)
		{};
	template<class Q>
	stRect(const stRect<Q>& rst) : 
		left(rst.left),top(rst.top),right(rst.right),bottom(rst.bottom)
		{}
	template<class Q>
	void operator=(const stRect<Q>& rst)
	{
		left(rst.left);
		top(rst.top);
		right(rst.right);
		bottom(rst.bottom);
	}
	T Width() const
	{
		return (right - left);
	}
	T Height() const
	{
		return (bottom - top);
	}
	stRect<T> operator&(const stRect<T>& rc) const
	{
		stRect<T> ret;
		if( left > rc.right || rc.left > right || 
			top > rc.bottom || rc.top > bottom )
			return ret;
		
		ret.left = left > rc.left ? left : rc.left;
		ret.top = top > rc.top ? top : rc.top;
		ret.right = right < rc.right ? right : rc.right;
		ret.bottom = bottom < rc.bottom ? bottom : rc.bottom;
		return ret;
	}
	bool empty() const
	{
		if( IsZero(left) && IsZero(top) &&
			IsZero(right) && IsZero(bottom) )
			return true;
		return false;
	}
	bool Contain(const stPoint<T>& pt) const
	{
		if( left <= pt.x && right >= pt.x &&
			top <= pt.y && bottom >= pt.y )
			return true;
		return false;
	}
	bool Contain(const stRect<T>& rc) const
	{
		if( left <= rc.left && right >= rc.left &&
			left <= rc.right && right >= rc.right &&
			top <= rc.top && bottom >= rc.bottom &&
			top <= rc.bottom && bottom >= rc.bottom )
			return true;
		return false;
	}


};

typedef stRect<long32> stRectI;
typedef stRect<Real> stRectF;
typedef stRect<int16> stRectI16;

class Bitwise
{
public:
	template<typename T>
    static FORCEINLINE bool isPO2(T n)
    {
        return (n & (n-1)) == 0;
    }
};